package bcontractor;

import static bcontractor.builders.api.KnowledgeBaseBuilder.aKnowledgeBase;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

import java.util.Arrays;

import org.junit.Before;
import org.junit.Test;

import bcontractor.api.SentenceSet;
import bcontractor.propositional.PropositionalSentence;
import bcontractor.propositional.SentenceParser;

/**
 * Teste básico para KnowledgeBase
 * 
 * @author lundberg
 * 
 */
public class KnowledgeBaseShould {

    private SentenceSet<PropositionalSentence> base;

    private SentenceParser parser;

    private PropositionalSentence a, b;

    @Before
    public void init() {
        this.base = aKnowledgeBase().build();
        this.parser = new SentenceParser();
        this.a = this.parser.create("a");
        this.b = this.parser.create("b");
    }

    @Test
    public void implementEqualsAndHashCode() {
        assertThat(this.base.hashCode(), not(System.identityHashCode(this.base)));
        assertThat(this.base.equals(this.base), is(true));
        assertThat(this.base.equals(this.base.with(this.a)), is(false));
        assertThat(this.base.hashCode(), not(this.base.with(this.a).hashCode()));
        assertThat(this.base.toString(), not(containsString("@")));
    }

    @Test
    public void beInitiallyEmpty() {
        assertThat(this.base.size(), is(0));
    }

    @Test
    public void beImmutable() {
        SentenceSet<PropositionalSentence> expanded = this.base.with(this.a);
        assertThat(this.base.contains(this.a), is(false));
        assertThat(this.base, not(is(expanded)));
    }

    @Test
    public void expandsStoringSingleSentence() {
        SentenceSet<PropositionalSentence> expanded = this.base.with(this.a);
        assertThat(expanded.contains(this.a), is(true));
    }

    @Test
    public void expandsStoringMultipleSentences() {
        SentenceSet<PropositionalSentence> expanded = this.base.with(Arrays.asList(this.a, this.b));
        assertThat(expanded.contains(this.a), is(true));
        assertThat(expanded.contains(this.b), is(true));
    }
}
